/**
 * 地图
 */
var mapChart = {
  /**
   * 初始化
   */
  init: function () {
    this.state = {
      rainData: [], // 所有的降雨量数据
      proData: [], // 所有的产量数据

      renderRainData: [], // 最终渲染图表用的降雨量数据
      renderProData: [], // 最终渲染图表用的产量数据

      crops: [], // 所有的 crops
      crop: "", // 当前图表对应的 crop，初始是 crops[0]
      years: [], // 所有的 Crop_Year
      year: "", // 当前图表对应的 year，初始是 years[0]

    }
    this.getData();
  },
  /**
   * 获取数据
   */
  getData: function () {
    var self = this;
    d3.csv('data/new_rain.csv', function (error, data) {
      if (error) {
        console.error(error);
      }
      self.state.rainData = data;
    })
    d3.csv('data/crop_production.csv', function (error, data) {
      if (error) {
        console.error(error);
      }
      self.state.proData = data.filter(function (d) {
        return d.Production // 去掉空值脏数据
      })
      self.render();
    })
  },
  /**
   * 渲染图表
   */
  render: function () {
    this.renderCrops();
    this.renderYears();
    this.filterData();
  },
  // 渲染 crops
  renderCrops: function () {
    var data = this.state.proData;
    var crops = [];
    var cropsSelectDom = "";
    data.forEach(function (d) {
      if (crops.indexOf(d.Crop.trim()) === -1) {
        crops.push(d.Crop.trim())
      }
    })
    this.state.crops = crops;
    this.state.crop = crops[0];
    crops.forEach(function (d) {
      cropsSelectDom += "<option>" + d.trim() + "</option>"
    })
    $('.map-crops-list').html(cropsSelectDom)
  },
  // 渲染 years
  renderYears: function () {
    var data = this.state.proData;
    var years = [];
    var yearSelectDom = "";
    data.forEach(function (d) {
      if (years.indexOf(parseInt(d.Crop_Year, 10)) === -1) {
        years.push(parseInt(d.Crop_Year, 10))
      }
    })
    this.state.years = years.sort();
    this.state.year = years[0];
    years.forEach(function (d) {
      yearSelectDom += "<option>" + d + "</option>"
    })
    $('.map-years-list').html(yearSelectDom)
  },
  filterData: function() {
    var year = this.state.year;
    var crop = this.state.crop;
    var rainData = this.state.rainData;
    var proData = this.state.proData;
    // 按照特定年份 -- 选中的年份过滤降雨数据
    var renderRainData = rainData.filter(function(d) {
      return parseInt(d.YEAR, 10) == year;
    })
    this.state.renderRainData = renderRainData;

    // 按照 crop 和 year 过滤 产量数据
    //另外还有两个额外条件：
    //1.时间纬度为整年,
    //2.地区: 一个State_Name包含多个District_Name 怎么取值呢？取District_Name和？
    var fileProData = proData.filter(function(d) {
      return d.Crop == crop && parseInt(d.Crop_Year, 10) == year
    })
    // 地区怎么取值呢？取和？ 此处按照取第一个值处理，即按照地区名字 - State_Name 进行去重
    var renderProData = [];
    var fileDisName = '';
    fileProData.forEach(function(d) {
      if(d.State_Name.trim() !== fileDisName) {
        fileDisName = d.State_Name.trim();
        renderProData.push(d)
      }
    })

    this.state.renderProData = renderProData;

    this.renderMap();
  },
  renderMap: function(){
    $('.map-chart').html('');
    var self = this;
    var renderRainData = this.state.renderRainData;
    var renderProData = this.state.renderProData;
    //求最大值和最小值
    var maxRainValue = d3.max(renderRainData, function(d) {
      return parseFloat(d.ANNUAL);
    })
    var minRainValue = 0;

    //定义一个线性比例尺，将最小值和最大值之间的值映射到[0, 1]
    var linear = d3.scale.linear()
      .domain([minRainValue, maxRainValue])
      .range([0, 1]);

    //定义最小值和最大值对应的颜色
    var a = d3.rgb(0, 255, 255); //浅蓝色
    var b = d3.rgb(0, 0, 255); //蓝色

    //颜色插值函数
    var computeColor = d3.interpolate(a, b);

    // 设置绘制撒点圆圈半径的比例尺
    var maxProValue = d3.max(renderProData,function(d) {
      return parseFloat(d.Production, 10)
    })
    var minProValue = d3.min(renderProData, function (d) {
      return parseFloat(d.Production, 10)
    })
    var minR = 10
    var maxR = 18
    var linearCR = d3.scale.linear()
      .domain([minProValue, maxProValue])
      .range([minR, maxR])

    var width = 1170;
    var height = 500;
    var svg = d3.select('.map-chart');
    //定义地图的投影
    var projection = d3.geo.mercator()
      .center([77.13, 28.37])
      .scale(900)
      .translate([width / 2, height / 2 - 100]);
    //定义地形路径生成器
    var path = d3.geo.path()
      .projection(projection); //设定投影
    //颜色比例尺
    var color = d3.scale.category20();
    //请求json
    d3.json("script/India.json", function (error, root) {
      if (error) return console.error(error);
      // 绘制地图 path
      var features = root.features;
      var groups = svg.append("g");
      groups.selectAll("path")
        .data(root.features)
        .enter()
        .append("path")
        .attr("class", "province")
        .style("fill", function (d, i) {
          var pathName = d.properties.name ? d.properties.name : '';
          var value = 0;
          renderRainData.forEach(function(d) {
            if(d.SUBDIVISION.toLowerCase() == pathName.toLowerCase()) {
              value = d.ANNUAL
            }
          })
          var t = linear(value);
          var color = computeColor(t);
          return color.toString();
        })
        .attr("d", path) //使用路径生成器
        .on('mousemove', function(d) {
          var event = d3.event;
          var top = d3.event.pageY;
          var left = d3.event.pageX;
          
          var tolData = renderProData.filter(function(pro) {
            return d.properties.name.toLowerCase() === pro.State_Name.toLowerCase()
          })
          var option = {
            el: '.auto-tooltip',
            location: {
              x: left,
              y: top
            },
            data: [{
              name: '地区',
              value: d.properties.name
            }, {
              name: '产量',
              value: tolData[0] ? parseFloat(tolData[0].Production, 10) : '暂无数据'
            }]
          }
          var el = self.tooltip(option)
          el.show()
        })
        .on('mouseout', function () {
          $('.auto-tooltip').hide()
        })
      // 绘制地图撒点
      var dotes = svg.append('g').attr('class','dotes');
      var dote = dotes.selectAll('.dote')
        .data(renderProData)
        .enter()
        .append('g')
        .attr('class', 'dote')
      
      dote.append('circle')
        .attr('cx', function(d) {
          var prop = features.filter(function (f) {
            return f.properties.name === d.State_Name
          })
          var centroid = path.centroid(prop[0]);
          return centroid[0]
        })
        .attr('cy', function (d) {
          var prop = features.filter(function (f) {
            return f.properties.name === d.State_Name
          })
          var centroid = path.centroid(prop[0]);
          return centroid[1]
        })
        .attr('r', function(d) {
          return linearCR(parseFloat(d.Production))
        })
        .attr({
          'stroke-width': 3,
          'stroke': '#54d6ff',
          'fill': 'rgb(109, 167, 107)'
        })
        
    });
    //定义一个线性渐变
    var defs = svg.append("defs");

    var linearGradient = defs.append("linearGradient")
      .attr("id", "linearColor")
      .attr("x1", "0%")
      .attr("y1", "0%")
      .attr("x2", "100%")
      .attr("y2", "0%");

    var stop1 = linearGradient.append("stop")
      .attr("offset", "0%")
      .style("stop-color", a.toString());

    var stop2 = linearGradient.append("stop")
      .attr("offset", "100%")
      .style("stop-color", b.toString());

    //添加一个矩形，并应用线性渐变
    var colorRect = svg.append("rect")
      .attr("x", 20)
      .attr("y", 490)
      .attr("width", 140)
      .attr("height", 30)
      .style("fill", "url(#" + linearGradient.attr("id") + ")");

    //添加文字
    var minValueText = svg.append("text")
      .attr("class", "valueText")
      .attr("x", 20)
      .attr("y", 490)
      .attr("dy", "-0.3em")
      .text(function () {
        return minRainValue;
      });

    var maxValueText = svg.append("text")
      .attr("class", "valueText")
      .attr("x", 160)
      .attr("y", 490)
      .attr("dy", "-0.3em")
      .text(function () {
        return maxRainValue;
      });

    this.bindEvent();
  },
  tooltip: function (option) {
    var el = option.el
    var location = option.location
    var data = option.data
    var text = ''
    for (var i = 0, length = data.length; i < length; i++) {
      if (length == 1) {
        text += data[i].name + '<br>' + data[i].value
      } else {
        text += data[i].name + '：' + data[i].value + '<br>'
      }
    }
    $(el).html(text)
    var globalWidth = $('body').outerWidth()
    var globalHeight = $('body').outerHeight()
    var elWidth = $(el).outerWidth()
    var elHeight = $(el).outerHeight()
    location.x = location.x - elWidth / 2
    location.y = location.y - elHeight - 10
    if (location.x + elWidth / 2 > globalWidth) {
      location.x = globalWidth - elWidth
    }
    $(el).css({
      left: location.x,
      top: location.y
    })
    return $(el)
  },
  bindEvent: function() {
    var self = this;
    $('.map-crops-list').off().on('change', function () {
      var crop = $('.map-crops-list').val();
      self.state.crop = crop;
      self.filterData();
    })
    $('.map-years-list').off().on('change', function () {
      var year = $('.map-years-list').val();
      self.state.year = year;
      self.filterData();
    })
  }

}